//
// dmBridge: a data access framework for CONTENTdm(R)
//
// Copyright © 2009, 2010, 2011 Board of Regents of the Nevada System of Higher
// Education, on behalf of the University of Nevada, Las Vegas
//

/**
 * dmBridge advanced search view script
 * Requires YUI 3
 * 
 * @author Alex Dolski <alex.dolski@unlv.edu>
 */

view = {
	// dmCollection objects will be lazy-loaded into this global, keyed by
	// alias
	collections: {}
};

YUI().use("node-base", function(Y) {
	Y.on("domready", function(e) {
		selectedFieldDidChange(e);
		Y.all("input.dmSubmit").each(function() {
			this.set("disabled", true);
		});
	});

	Y.all("input.dmSearchField").on("keyup", function(e) {
		textFieldDidChange(e.target);
	});

	Y.all(".dmSearchFieldSelect").on("change", function(e) {
		selectedFieldDidChange(e);
	});
	Y.all("#dmDateSearchField").on("change", function(e) {
		selectedFieldDidChange(e);
	});

	Y.all(".dmSearchCollectionList input").on("change", function(e) {
		collectionChecked(e.target);
	});

	Y.all("#dmDateQualifier").on("change", function(e) {
		dateSearchTypeDidChange(e);
	});

	Y.all("a.dmCheckAll").on("click", function(e) {
		setAllCollectionsChecked(e, true);
	});
	Y.all("a.dmUncheckAll").on("click", function(e) {
		setAllCollectionsChecked(e, false);
	});
});

YUI().use("autocomplete", "autocomplete-highlighters", function (Y) {
	autoCompleteOptions = {
		resultHighlighter: "phraseMatch",
		resultListLocator: "dmBridgeResponse.vocabulary",
		source: Y.one(".dmBridgeBaseURI").get("value")
			+ "/api/1/vocabulary/suggest.jsonp?callback={callback}&CISOFIELD1=title&CISOROOT="
			+ Y.one(".dmBridgeSelectedCollection").get("value")
			+ "&CISOBOX1={query}"
	};
	Y.all(".dmSearchField").plug(Y.Plugin.AutoComplete,
		autoCompleteOptions);
});

function selectedFieldDidChange(e) {
	if (!e) {
		return;
	}
	// update the autocomplete URL of the corresponding text field
	YUI().use("node-base", function(Y) {
		autoCompleteOptions.source = autoCompleteOptions.source.replace(
			/CISOFIELD1=\w+/,
			"CISOFIELD1=" + e.target.get("value"));
	});
}

/**
 * Repopulates the field select menu(s) when a collection has been checked or
 * unchecked in the list of collections to search.
 */
function collectionChecked(input) {
	if (!input) {
		return;
	}

	// display spinner
	input.get("parentNode").addClass("loading");

	YUI({filter: "raw"}).use("node-base", "io", "json-parse", function(Y) {
		var loadingSucceeded = function(x, o) {
			try {
				var responseJson = Y.JSON.parse(o.responseText);
				var alias = responseJson.dmBridgeResponse.dmCollection.alias;
				view.collections[alias] = responseJson.dmBridgeResponse.dmCollection;
				addOrRemoveFieldsFromCollection(input);
			} catch (e) {
				console.log(e.message);
			}
			loadingComplete();
		}

		var loadingFailed = function(x, o) {
			//console.log("Async call failed");
			loadingComplete();
		}

		var loadingComplete = function() {
			// hide spinner
			input.get("parentNode").removeClass("loading");
			input.ancestor("form").one(".dmSubmit").set("disabled",
				(input.ancestor("ul").all("input:checked").isEmpty()));
		}

		var addOrRemoveFieldsFromCollection = function(input) {
			input.ancestor("fieldset").all(".dmSearchFieldSelect").each(function() {
				var alias = input.get("value");
				if (input.get("checked")) { // we are adding a collection
					for (var nick in view.collections[alias].fields) {
						// if the select menu already contains a field with the
						// same nick, don't add another one
						var proceed = true;
						this.get("childNodes").each(function() {
							if (this.get("value") == nick) {
								proceed = false;
								return;
							}
						});
						if (proceed) {
							var newopt = this.create(
								'<option value="' + nick + '">'
									+ view.collections[alias].fields[nick].name + '</option>');
							this.append(newopt);
						}
					}
				} else { // we are removing a collection; remove all of its
					// fields that are not shared by an existing collection

					// get a list of all fields from all checked collections
					var availableFields = [];
					input.ancestor("ul").all("input:checked").each(function() {
						if (view.collections.hasOwnProperty(this.get("value"))) {
							for (nick in view.collections[this.get("value")].fields) {
								var field = view.collections[this.get("value")].fields[nick];
								field.nick = nick;
								availableFields.push(field);
							}
						}
					});

					// remove each field in the menu if it is not present in
					// the array of available fields
					this.get("childNodes").each(function() {
						var match = false;
						for (var i = 0; i < availableFields.length; i++) {
							if (this.get("value") == availableFields[i].nick) {
								match = true;
							}
						}
						if (!match) {
							this.remove();
						}
					});
				}
			});
		}

		var callback = {
			timeout: 5000,
			on: {
				success: function(x, o) {
					loadingSucceeded(x, o);
				},
				failure: function(x, o) {
					loadingFailed(x, o);
				}
			}
		}

		if (!view.collections.hasOwnProperty(input.get("value"))) {
			Y.io(Y.one(".dmBridgeBaseURI").get("value") + "/api/1/collections"
				+ input.get("value") + ".json",
			callback);
		} else {
			addOrRemoveFieldsFromCollection(input);
			loadingComplete();
		}
	});
}

function dateSearchTypeDidChange(e) {
	var begin = document.getElementById("dmBeginDateSelect");
	var end = document.getElementById("dmEndDateSelect");
	var end_label = document.getElementById("dmEndDateLabel");
	begin.style.display = "inline";
	end.style.display = "block";
	end_label.style.display = "inline-block";

	if (document.getElementById("dmDateQualifier").selectedIndex == 2) {
		begin.style.display = "none";
		end.style.display = "inline";
		end_label.style.display = "none";
	} else if (document.getElementById("dmDateQualifier").selectedIndex > 0) {
		end.style.display = "none";
		end_label.style.display = "none";
	}
}

function setAllCollectionsChecked(e, bool) {
	YUI().use("node-base", function(Y) {
		e.target.ancestor("form").all("div.dmSearchCollectionList input").each(function() {
			this.set("checked", bool);
			collectionChecked(this);
		});
	});
}

function textFieldDidChange(input) {
	var form = input.ancestor("form");
	var empty = true;
	form.all("input.dmSearchField").each(function() {
		if (this.get("value").length > 0) {
			empty = false;
			return;
		}
	});
	form.one("input.dmSubmit").set("disabled", empty);
}
